package com.customization.unionpay.market.workflowaction;

import com.alibaba.fastjson.JSONObject;
import com.customization.unionpay.market.maketEnum.InstructionEnum;
import com.customization.unionpay.market.util.FormDataUtils;
import com.customization.unionpay.contract.serivce.impl.ContractBaseServiceImpl;
import com.customization.unionpay.market.util.PropUtils;
import org.apache.commons.lang.StringUtils;
import weaver.generalledger.action.ZzgdExecuteInstrucitonAction;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.company.SubCompanyComInfo;
import weaver.hrm.resource.ResourceComInfo;
import weaver.integration.logging.Logger;
import weaver.integration.logging.LoggerFactory;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import weaver.workflow.request.RequestManager;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * @author sjm
 * @description 核销报账流程相关
 */
public class VerificationAndReimbursementAction implements Action {

    private static final Logger log = LoggerFactory.getLogger(VerificationAndReimbursementAction.class);

    @Override
    public String execute(RequestInfo requestInfo) {
        log.info("进入核销报账流程!");
        RequestManager rm = requestInfo.getRequestManager();

        try {
            String requestid = String.valueOf(rm.getRequestid());

            String tableName = rm.getBillTableName();          // 表单名称
            log.info("tableName:" + tableName);

            // 流程表单id
            int formId = rm.getFormid();
            // 流程标题
            String requestName = requestInfo.getDescription();

            Map<String, Object> allFormData = com.customization.unionpay.market.util.FormDataUtils.getAllFormData(requestInfo);

            Map<String, String> mainMap = (Map<String, String>) allFormData.get("mainMap");
            // 所有明细表的值
            Map<String, Map<String, Map<String, String>>> detailMap = (Map<String, Map<String, Map<String, String>>>) allFormData.get("detailMap");

            // sfwdxy   是否为大协议
            String sfwdxy = mainMap.get("sfwdxy");
            log.info("sfwdxy："+sfwdxy);
            String sfwdxyName = com.customization.unionpay.market.util.FormDataUtils.getItemName(formId, "sfwdxy", sfwdxy);
            log.info("sfwdxyName："+sfwdxyName);

            String bdh = mainMap.get("bdh");
            log.info("bdh："+bdh);

            // 调用合同 本次核销金额】写入合同明细行【列账金额】
            ContractBaseServiceImpl contractBaseService = new ContractBaseServiceImpl();
            Map<String, Map<String, String>> dt1 = detailMap.get("dt1");
            for (String key : dt1.keySet()) {
                Map<String, String> value = dt1.get(key);
                // 本次核销金额
                String bchxje = value.get("bchxje");
                log.info("bchxje："+bchxje);
                // 履约明细号
                Integer lymxh = Integer.valueOf(value.get("lymxh"));
                log.info("lymxh："+lymxh);
                contractBaseService.updateHx(lymxh,bchxje);
            }

            // 预算 是否为大协议 =否
            if("否".equals(sfwdxyName)){
                // fplx     发票类型
                String fplx = mainMap.get("fplx");
                String fplxName = com.customization.unionpay.market.util.FormDataUtils.getItemName(formId, "fplx", fplx);
                log.info("发票类型："+fplxName);

                // hdhxlx   核定/核销类型
                String hdhxlx = mainMap.get("hdhxlx");
                String hdhxlxName = com.customization.unionpay.market.util.FormDataUtils.getItemName(formId, "hdhxlx", hdhxlx);
                log.info("核定/核销类型："+hdhxlxName);
                // zjly     资金来源
                String zjly = mainMap.get("zjly");
                String zjlyName = com.customization.unionpay.market.util.FormDataUtils.getItemName(formId, "zjly", zjly);
                log.info("资金来源："+zjlyName);
                // sfwjdyw  是否为积点业务
                String sfwjdyw = mainMap.get("sfwjdyw");
                String sfwjdywName = com.customization.unionpay.market.util.FormDataUtils.getItemName(formId, "sfwjdyw", sfwjdyw);
                log.info("是否为积点业务："+sfwjdywName);

                // 主 活动核销日期        hdhxrq
                String hdhxrq = mainMap.get("hdhxrq");
                log.info("hdhxrq："+hdhxrq);
                // 主 预算控制期      rzrq
                String rzrq = mainMap.get("rzrq");

                String hdhxrqStr = com.customization.unionpay.market.util.FormDataUtils.changeDateString("yyyy-MM-dd", hdhxrq, "yyyy");
                log.info("活动核销日期的年份："+hdhxrqStr); // 为空执行本年预算
                String rzrqStr = com.customization.unionpay.market.util.FormDataUtils.changeDateString("yyyy-MM-dd", rzrq, "yyyy");
                log.info("预算控制期的年份："+rzrqStr);

                JSONObject params = new JSONObject();
                String instruction = "";
                if("内外部联合营销".equals(zjlyName)){
                    if("变更核定".equals(hdhxlxName)){
                        String yspdhdce = StringUtils.isNotBlank(mainMap.get("yspdhdce")) ? mainMap.get("yspdhdce"):"0" ;
                        log.info("yspdhdce："+yspdhdce);
                        Double yspdhdceDb = Double.valueOf(yspdhdce);
                        if(yspdhdceDb >= 0){
                            // + 占用且执行
                            // 预算 预算判断-核定差额	    主表  1.资金来源=内外部联合营销； 2.核定/核销类型=变更核定 终审-释放占用且执行 SFZYQZX
                            params = getVerificationAndReimbursementParamsAddMiddle(requestName,rzrq,rzrqStr,mainMap,detailMap,bdh,tableName,requestid,true,yspdhdce);
                            instruction = com.customization.unionpay.market.maketEnum.InstructionEnum.SFZYQZX.toString();
                        }else {
                            yspdhdce = yspdhdce.split("-")[1];
                            // - 释放执行且占用
                            // 判断年份
                            // 预算 预算判断-核定差额	    主表  1.资金来源=内外部联合营销； 2.核定/核销类型=变更核定 终审-释放占用且执行 SFZYQZX
                            params = getVerificationAndReimbursementParamsAddMiddle(requestName, rzrq, rzrqStr, mainMap, detailMap, bdh, tableName, requestid, true, yspdhdce);
                            if("".equals(hdhxrqStr) || hdhxrqStr.equals(rzrqStr)) {
                                instruction = com.customization.unionpay.market.maketEnum.InstructionEnum.SFZXQZY.toString();
                            }else {
                                instruction = com.customization.unionpay.market.maketEnum.InstructionEnum.XMSFZXQZY.toString();
                            }
                        }
                    }else {
                        String yspdschdje = StringUtils.isNotBlank(mainMap.get("yspdschdje")) ? mainMap.get("yspdschdje"):"0";
                        log.info("yspdschdje："+yspdschdje);
                        Double yspdschdjeDb = Double.valueOf(yspdschdje);
                        if(yspdschdjeDb >= 0){
                            // + 占用且执行
                            // 预算 预算判断-首次核定金额	主表  1.资金来源=内外部联合营销； 2.核定/核销类型=首次核定 终审-释放占用且执行 SFZYQZX
                            params = getVerificationAndReimbursementParamsAddMiddle(requestName,rzrq,rzrqStr,mainMap,detailMap,bdh,tableName,requestid,true,yspdschdje);
                            instruction = com.customization.unionpay.market.maketEnum.InstructionEnum.SFZYQZX.toString();
                        }else {
                            // - 释放执行且占用
                            // 判断年份
                            // 预算 预算判断-首次核定金额	主表  1.资金来源=内外部联合营销； 2.核定/核销类型=首次核定 终审-释放占用且执行 SFZYQZX
                            yspdschdje = yspdschdje.split("-")[1];
                            params = getVerificationAndReimbursementParamsAddMiddle(requestName,rzrq,rzrqStr,mainMap,detailMap,bdh,tableName,requestid,true,yspdschdje);
                            if("".equals(hdhxrqStr) || hdhxrqStr.equals(rzrqStr)) {
                                instruction = com.customization.unionpay.market.maketEnum.InstructionEnum.SFZXQZY.toString();
                            }else {
                                instruction = com.customization.unionpay.market.maketEnum.InstructionEnum.XMSFZXQZY.toString();
                            }
                        }
                    }
                    log.info("预算校验拼接参数："+params);
                    int yszjbFormId = Integer.parseInt(PropUtils.BB_LOG.getPropValue("marketSubject", "yszjb_form_id"));
                    int yszjbFormmodeId = Integer.parseInt(PropUtils.BB_LOG.getPropValue("marketSubject", "yszjb_formmode_id"));
                    String yszjbTableName = com.customization.unionpay.market.util.FormDataUtils.getTableName(yszjbFormId);
                    log.info("yszjbTableName：" + yszjbTableName);
                    com.customization.unionpay.market.util.FormDataUtils.addYuMiddleForm(yszjbFormId,yszjbFormmodeId,yszjbTableName,rm.getUser(),params);

                    log.info("instruction："+instruction);
                    ZzgdExecuteInstrucitonAction zzgdExecuteInstrucitonAction = new ZzgdExecuteInstrucitonAction();
                    zzgdExecuteInstrucitonAction.setZl(instruction);
                    String execute = zzgdExecuteInstrucitonAction.execute(requestInfo);
                    if("0".equals(execute)){
                        String messageid = requestInfo.getRequestManager().getMessageid();
                        log.info("messageid："+messageid);
                        String messagecontent = requestInfo.getRequestManager().getMessagecontent();
                        log.info("messagecontent："+messagecontent);
                        return Action.FAILURE_AND_CONTINUE;
                    }else {
                        log.info("预算调用成功！");
                    }
                }

                if("增值税发票".equals(fplxName)){
                    params = getVerificationAndReimbursementParamsAddMiddle(requestName,rzrq,rzrqStr,mainMap,detailMap,bdh,tableName,requestid,false,null);
                    if("".equals(hdhxrqStr) || hdhxrqStr.equals(rzrqStr)){
                        // 预算 预算判断-税额 明细表  1.发票类型=增值税发票； 2.活动核销日期的年份（含空）=预算控制期的年份  or （核定/核销类型=首次核定  and  资金来源=内外部联合营销）
                        // 终审-释放执行且占用
                        instruction =  com.customization.unionpay.market.maketEnum.InstructionEnum.SFZXQZY.toString();
                    }else {
                        // 预算 预算判断-税额 明细表  1.发票类型=增值税发票； 2.活动核销日期的年份（含空）≠预算控制期的年份
                        // 终审-项目释放执行且占用
                        instruction = com.customization.unionpay.market.maketEnum.InstructionEnum.XMSFZXQZY.toString();
                    }
                    log.info("预算校验拼接参数："+params);
                    int yszjbFormId = Integer.parseInt(PropUtils.BB_LOG.getPropValue("marketSubject", "yszjb_form_id"));
                    int yszjbFormmodeId = Integer.parseInt(PropUtils.BB_LOG.getPropValue("marketSubject", "yszjb_formmode_id"));
                    String yszjbTableName = com.customization.unionpay.market.util.FormDataUtils.getTableName(yszjbFormId);
                    log.info("yszjbTableName：" + yszjbTableName);
                    com.customization.unionpay.market.util.FormDataUtils.addYuMiddleForm(yszjbFormId,yszjbFormmodeId,yszjbTableName,rm.getUser(),params);

                    log.info("instruction："+instruction);
                    ZzgdExecuteInstrucitonAction zzgdExecuteInstrucitonAction = new ZzgdExecuteInstrucitonAction();
                    zzgdExecuteInstrucitonAction.setZl(instruction);
                    String execute = zzgdExecuteInstrucitonAction.execute(requestInfo);
                    if("0".equals(execute)){
                        String messageid = requestInfo.getRequestManager().getMessageid();
                        log.info("messageid："+messageid);
                        String messagecontent = requestInfo.getRequestManager().getMessagecontent();
                        log.info("messagecontent："+messagecontent);
                        return Action.FAILURE_AND_CONTINUE;
                    }else {
                        log.info("预算调用成功！");
                    }
                }

                if("是".equals(sfwjdywName)){
                    String yspdjdsyje = mainMap.get("yspdjdsyje");
                    log.info("yspdjdsyje："+yspdjdsyje);
                    params = getVerificationAndReimbursementParamsAddMiddle(requestName,rzrq,rzrqStr,mainMap,detailMap,bdh,tableName,requestid,true,yspdjdsyje);
                    if("".equals(hdhxrqStr) || hdhxrqStr.equals(rzrqStr)){
                        // 预算 预算判断-积点使用金额	主表  1.资金来源=内部营销；      2.是否为积点业务=是 终审-释放占用且执行 SFZYQZX
                        instruction = com.customization.unionpay.market.maketEnum.InstructionEnum.SFZXQZY.toString();
                    }else {
                        // 预算 预算判断-积点使用金额	主表  1.资金来源=内部营销；      2.是否为积点业务=是 终审-释放占用且执行 SFZYQZX
                        instruction = InstructionEnum.XMSFZXQZY.toString();
                    }
                    log.info("预算校验拼接参数："+params);
                    int yszjbFormId = Integer.parseInt(PropUtils.BB_LOG.getPropValue("marketSubject", "yszjb_form_id"));
                    int yszjbFormmodeId = Integer.parseInt(PropUtils.BB_LOG.getPropValue("marketSubject", "yszjb_formmode_id"));
                    String yszjbTableName = com.customization.unionpay.market.util.FormDataUtils.getTableName(yszjbFormId);
                    log.info("yszjbTableName：" + yszjbTableName);
                    FormDataUtils.addYuMiddleForm(yszjbFormId,yszjbFormmodeId,yszjbTableName,rm.getUser(),params);

                    log.info("instruction："+instruction);
                    ZzgdExecuteInstrucitonAction zzgdExecuteInstrucitonAction = new ZzgdExecuteInstrucitonAction();
                    zzgdExecuteInstrucitonAction.setZl(instruction);
                    String execute = zzgdExecuteInstrucitonAction.execute(requestInfo);
                    if("0".equals(execute)){
                        String messageid = requestInfo.getRequestManager().getMessageid();
                        log.info("messageid："+messageid);
                        String messagecontent = requestInfo.getRequestManager().getMessagecontent();
                        log.info("messagecontent："+messagecontent);
                        return Action.FAILURE_AND_CONTINUE;
                    }else {
                        log.info("预算调用成功！");
                    }
                }

            }else {
                log.info("当前是否大协议不为否！");
            }
        } catch (Exception e) {
            // 异常报错是填写异常信息，阻止流程继续流转
            requestInfo.getRequestManager().setMessageid("10001");
            requestInfo.getRequestManager().setMessagecontent(e.getMessage());
            return Action.FAILURE_AND_CONTINUE;
        }
        return Action.SUCCESS;
    }

    /**
     * 拼接预算参数到中间表
     * @param requestName
     * @param yskzq
     * @param yskzqStr
     * @param mainMap
     * @param detailMap
     * @param bdh            被执行单号
     * @param tableName
     * @param id
     * @param isMain
     * @param mainAmount
     * @return
     * @throws Exception
     */
    public JSONObject getVerificationAndReimbursementParamsAddMiddle(String requestName,String yskzq,String yskzqStr,Map<String, String> mainMap,Map<String, Map<String, Map<String, String>>> detailMap,String bdh,String tableName,String id,boolean isMain,String mainAmount) throws Exception {
        ResourceComInfo rci = new ResourceComInfo();
        DepartmentComInfo dci = new DepartmentComInfo();
        SubCompanyComInfo scci = new SubCompanyComInfo();

        String projectCode = mainMap.get("project_code");
        String sqr = mainMap.get("sqr");

        String workcode = rci.getWorkcode(sqr);
        String lastname = rci.getLastname(sqr);

        String bzbm = mainMap.get("bzbm");

        String departmentCode = dci.getDepartmentCode(bzbm);
        String departmentname = dci.getDepartmentname(bzbm);

        String bzgs = mainMap.get("bzgs");

        String subCompanyName = scci.getSubCompanyname(bzgs);
        String subCompanyCode = scci.getSubCompanyCode(bzgs);

        String bzsy = mainMap.get("bzsy");

        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());

        Map<String, Map<String, String>> dt1 = detailMap.get("dt1");

        JSONObject param = new JSONObject();
        for (String key : dt1.keySet()) {
            Map<String, String> value = dt1.get(key);
            String jjsx = value.get("jjsx");
            log.info("jjsx:"+jjsx);
            // 预算判断-税额
            String yspdse = "".equals(value.get("yspdse")) ? "0" : (value.get("yspdse") == null ? "0" : value.get("yspdse"));
            String yszrzx = value.get("yszrzx");
            String yskm = value.get("yskm");
            String ysxsqd = value.get("ysxsqd");


            // 主 项目编号                 ysxm                预算项目
            param.put("ysxm",projectCode);
            // 明细  预算科目               yskm	             预算科目
            param.put("yskm",yskm);
            // 明细  预算责任中心           zhdw	             执行单位
            param.put("zhdw",yszrzx);
            //                           ysqjn               预算期间（年）	      必传，预算入账期间加工成4位年份
            param.put("ysqjn",yskzqStr);
            // 明细                      je                   金额

            if(isMain){
                mainAmount = "".equals(mainAmount) ? "0" : (mainAmount == null ? "0" : mainAmount);
                param.put("je",mainAmount);
            }else {
                param.put("je",yspdse);
            }

            // 主 表单号                  bzydjh               被占用单据号	     非必传，下列情况必传： 释放占用且执行,释放执行且占用、释放占用（必传）, 占用（特殊情况必传）
            param.put("bzydjh",ysxsqd);
            // 主 表单号                  zhdjh                执行单据号        必传
            param.put("zhdjh",bdh);
            // 主 预算控制期               yskzq              预算控制期           必传，预算的入账期间
            param.put("yskzq",yskzq);
            //                           zhrq	            执行日期	           必传，当前日期
            param.put("zhrq",format);
            //                           zhdjlx	            执行单据类型	        必传
            param.put("zhdjlx","核销报账流程");
            // 主 申请人                   bzr                  报账人          必传，工号-姓名
            param.put("bzr",workcode+"-"+lastname);
            //                           lyxt	            来源系统	           必传，智慧财务平台
            param.put("lyxt","智慧财务平台");
            // 主 报账事由                 sm	                 说明  	        必传，各报账单的主表备注字段
            param.put("sm",bzsy);
            // 主 报账部门                 tdrbm                报账部门        必传，部门编码-部门名称
            param.put("tdrbm",departmentCode+"-"+departmentname);
            // 主 报账公司                 szgs                 报账公司        必传，公司编码-公司名称
            param.put("szgs",subCompanyCode+"-"+subCompanyName);
            // 明细  经济事项              jjsx                  经济事项             必传，经济事项编号
            param.put("jjsx",jjsx);
            // 明细  事项
            param.put("event","");
            // 明细  来源id
            param.put("lylc",id);
            // 明细  来源业务表名
            param.put("lyywbm",tableName);
        }

        return param;
    }
}
